home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / LANG / C / LIB / UNIXLIB37B / !UnixLib37 / src / c / strtod < prev    next >
Text File  |  1996-11-09  |  2KB  |  99 lines

  1. /****************************************************************************
  2.  *
  3.  * $Source: /unixb/home/unixlib/source/unixlib37/src/c/RCS/strtod,v $
  4.  * $Date: 1996/05/06 09:03:13 $
  5.  * $Revision: 1.2 $
  6.  * $State: Rel $
  7.  * $Author: unixlib $
  8.  *
  9.  * $Log: strtod,v $
  10.  * Revision 1.2  1996/05/06 09:03:13  unixlib
  11.  * Updates to sources made by Nick Burrett, Peter Burwood and Simon Callan.
  12.  * Saved for 3.7a release.
  13.  *
  14.  * Revision 1.1  1996/04/19 21:26:42  simon
  15.  * Initial revision
  16.  *
  17.  ***************************************************************************/
  18.  
  19. static const char rcs_id[] = "$Id: strtod,v 1.2 1996/05/06 09:03:13 unixlib Rel $";
  20.  
  21. #include <ctype.h>
  22. #include <stdlib.h>
  23.  
  24. #define MAXEXP    308        /* maximum decimal exponential for IEEE double */
  25.  
  26. /* recognizes: [spaces][sign][digs][[.][digs]][[e|E][space|sign][int]] */
  27.  
  28. /* this is the most efficient strtod() can be, without resorting to
  29.  * assuming IEEE 'D' or some other floating point representation */
  30.  
  31. double
  32. strtod (register const char *s, char **end)
  33. {
  34.   register double r, p;
  35.   register unsigned int x;
  36.   register int r_, x_;
  37.   const char *_s;
  38.  
  39.   r = 0;
  40.   r_ = 0;
  41.  
  42.   if (!s)
  43.     return (r);
  44.  
  45.   while (isspace (*s++));
  46.   s--;
  47.  
  48.   if (*s == '-' || *s == '+')
  49.     {
  50.       if (*s == '-')
  51.     r_ = 1;
  52.       s++;
  53.     }
  54.  
  55.   while (isdigit (*s))
  56.     {
  57.       r = r * 10 + (int) (*s - '0');
  58.       s++;
  59.     }
  60.  
  61.   if (*s != '.')
  62.     goto integer;
  63.  
  64.   s++;
  65.   p = 1;
  66.   while (isdigit (*s))
  67.     {
  68.       r = r * 10 + (int) (*s - '0');
  69.       p *= 10;
  70.       s++;
  71.     }
  72.   r /= p;
  73.  
  74. integer:if (!(*s == 'e' || *s == 'E'))
  75.     goto ret;
  76.  
  77.   x_ = (int) strtol (++s, (char **) &_s, 0);
  78.   s = _s;
  79.  
  80.   x_ = (x_ < 0) ? ((x = (unsigned int) (-x_)), 1) : ((x = (unsigned int) x_), 0);
  81.  
  82.   if (x > MAXEXP)
  83.     {
  84.       r_ = 0;
  85.       r = 0;
  86.       goto ret;
  87.     }
  88.  
  89.   p = 1;
  90.   while (x)
  91.     p *= 10, x--;
  92.   r = (x_) ? (r / p) : (r * p);
  93.  
  94. ret:if (end)
  95.     *end = (char *) s;
  96.  
  97.   return (r_ ? -r : r);
  98. }
  99.